/*  Lognsoft Copyright 2010
    BSD License
*/

#ifndef __COUMO_TYPES_H__
#define __COUMO_TYPES_H__

#if !defined(WINDOWS) && ( defined(_WIN32) || defined(_WIN64) )
  #define WINDOWS
#endif

#ifndef LN_INT64
  #ifdef WINDOWS
    #define LN_INT64 __int64
  #else
    #define LN_INT64 long long
  #endif
#endif

#ifndef LN_WCHAR
  #define LN_WCHAR unsigned short
#endif

enum
{
  LN_VT_NONE         ,
  LN_VT_NULL         ,
  LN_VT_INT32        ,
  LN_VT_UINT32       ,
  LN_VT_INT64        ,
  LN_VT_UINT64       ,

  LN_VT_DOUBLE       ,
  LN_VT_BOOL         ,

  LN_VT_DATE         ,
  LN_VT_TIME         ,
  LN_VT_DATETIME     ,
  LN_VT_TIMESTAMP    ,

  LN_VT_MONETARY     ,

  LN_VT_OBJECT_BEGIN ,
  LN_VT_BINARY       = LN_VT_OBJECT_BEGIN,
  LN_VT_STRING       ,
  LN_VT_WSTRING      ,
  LN_VT_BIGINT       ,

  LN_VT_ARRAY_INT    ,
  LN_VT_ARRAY_I64    ,
  LN_VT_ARRAY        ,
  LN_VT_MAP          ,
};

/*
  data type convert table

  --- Dest ----
 |
 S
 r
 c
 |
 |

-----------------------------------------------------------------------------
          |0|NUL|I|UI|I64|U64|DBL|BL|DT|T|DT|TS|$|BIN|S|WS|BI|AI|A64|ARR|MAP|
____________________________________________________________________________
NONE      |=|   | |  |   |   |   |  |  | |  |  | |   | |  |  |  |   |   |   |
NULL      | | = | |  |   |   |   |  |  | |  |  | |   | |  |  |  |   |   |   |
INT32     | |   |=|  |   |   |   |  |  | |  |  | |   | |  |  |  |   |   |   |
UINT32    | |   | | =|   |   |   |  |  | |  |  | |   | |  |  |  |   |   |   |
INT64     | |   | |  | = |   |   |  |  | |  |  | |   | |  |  |  |   |   |   |
UINT64    | |   | |  |   | = |   |  |  | |  |  | |   | |  |  |  |   |   |   |
DOUBLE    | |   | |  |   |   | = |  |  | |  |  | |   | |  |  |  |   |   |   |
BOOL      | |   | |  |   |   |   | =|  | |  |  | |   | |  |  |  |   |   |   |
DATE      | |   | |  |   |   |   |  |= | |  |  | |   | |  |  |  |   |   |   |
TIME      | |   | |  |   |   |   |  |  |=|  |  | |   | |  |  |  |   |   |   |
DATETIME  | |   | |  |   |   |   |  |  | |= |  | |   | |  |  |  |   |   |   |
TIMESTAMP | |   | |  |   |   |   |  |  | |  |= | |   | |  |  |  |   |   |   |
MONETARY  | |   | |  |   |   |   |  |  | |  |  |=|   | |  |  |  |   |   |   |
BINARY    | |   | |  |   |   |   |  |  | |  |  | | = | |  |  |  |   |   |   |
STRING    | |   | |  |   |   |   |  |  | |  |  | |   |=|  |  |  |   |   |   |
WSTRING   | |   | |  |   |   |   |  |  | |  |  | |   | |= |  |  |   |   |   |
BIGINT    | |   | |  |   |   |   |  |  | |  |  | |   | |  |= |  |   |   |   |
ARRAY_INT | |   | |  |   |   |   |  |  | |  |  | |   | |  |  | =|   |   |   |
ARRAY_I64 | |   | |  |   |   |   |  |  | |  |  | |   | |  |  |  | = |   |   |
ARRAY     | |   | |  |   |   |   |  |  | |  |  | |   | |  |  |  |   | = |   |
MAP       | |   | |  |   |   |   |  |  | |  |  | |   | |  |  |  |   |   | = |
-----------------------------------------------------------------------------
*/

typedef unsigned LN_INT64 LN_DATE;
typedef unsigned LN_INT64 LN_TIME;
typedef unsigned LN_INT64 LN_DATETIME;
typedef unsigned LN_INT64 LN_TIMESTAMP;
typedef double            LN_MONETARY;

struct ln_variant_t;
struct ln_string_t;
struct ln_wstring_t;

struct ln_array_t;
struct ln_array_int_t;
struct ln_array_i64_t;

struct ln_map_t;
struct ln_bigint_t;

typedef struct ln_variant_t      LN_VARIANT;
typedef struct ln_variant_t    * LN_VARIANT_PTR;
typedef struct ln_string_t       LN_STRING;
typedef struct ln_string_t     * LN_STRING_PTR;
typedef struct ln_wstring_t      LN_WSTRING;
typedef struct ln_wstring_t    * LN_WSTRING_PTR;
typedef struct ln_array_t        LN_ARRAY;
typedef struct ln_array_t      * LN_ARRAY_PTR;
typedef struct ln_array_int_t    LN_ARRAY_INT;
typedef struct ln_array_int_t  * LN_ARRAY_INT_PTR;
typedef struct ln_array_i64_t    LN_ARRAY_I64;
typedef struct ln_array_i64_t  * LN_ARRAY_I64_PTR;
typedef struct ln_map_t          LN_MAP;
typedef struct ln_map_t        * LN_MAP_PTR;
typedef struct ln_bigint_t       LN_BIGINT;
typedef struct ln_bigint_t     * LN_BIGINT_PTR;

struct ln_stream_t;
struct ln_thread_t;
struct ln_type_map_t;

typedef struct ln_stream_t       LN_STREAM;
typedef struct ln_stream_t     * LN_STREAM_PTR;
typedef struct ln_thread_t       LN_THREAD;
typedef struct ln_thread_t     * LN_THREAD_PTR;
typedef struct ln_type_map_t     LN_TYPE_MAP;
typedef struct ln_type_map_t   * LN_TYPE_MAP_PTR;

#define LN_VARIANT_NULL_VALUE { {0},{0} }

extern const LN_TYPE_MAP_PTR * ln_types;

#define LN_STRING_INIT(v)  ((v)->size=(v)->buf_size=0,(v)->val=(void*)0)
#define LN_STRING_FREE(v)  do { if ((v)->val) free ((v)->val); LN_STRING_INIT(v); } while(0)
/*
 *
 */
struct ln_string_t
{
  char * val;
  int    size;
  int    buf_size;
};

struct ln_wstring_t
{
  LN_WCHAR * val;
  int         size;
};

struct ln_array_t
{
  LN_VARIANT_PTR val;
  int            size;
};

struct ln_array_int_t
{
  int   * val;
  int     size;
};

struct ln_array_i64_t
{
  LN_INT64   * val;
  int           size;
};

struct ln_map_t
{
  int  hash_size;
};

struct ln_variant_t
{
   union
   {
      unsigned int       uintval;
      int                intval ;
      unsigned LN_INT64  u64val ;
               LN_INT64  i64val ;
      double             realval;
      int                boolval;

      LN_TIME            time;
      LN_DATE            date;
      LN_DATETIME        datetime;
      LN_TIMESTAMP       timestamp;
      LN_STRING          string;
      LN_WSTRING         wstring;
      LN_STRING          bin;

      LN_ARRAY           array;
      LN_ARRAY_INT       int_array;
      LN_ARRAY_I64       i64_array;
      LN_MAP             map;
   }dt;

   short vt;
};

struct ln_type_map_t
{
  int (*clear) (LN_THREAD_PTR thrd, LN_VARIANT_PTR v);
  int (*hash)  (LN_VARIANT_PTR v);
  int (*chg)   (LN_THREAD_PTR thrd, LN_VARIANT_PTR v, int vt);

  int (*vtos)  (LN_THREAD_PTR thrd, LN_VARIANT_PTR v, char * s, int size);
  int (*stov)  (LN_THREAD_PTR thrd, LN_VARIANT_PTR v, const char* s, int size);

  int (*load)  (LN_THREAD_PTR thrd, LN_VARIANT_PTR v, LN_STREAM_PTR stream);
  int (*save)  (LN_THREAD_PTR thrd, LN_VARIANT_PTR v, LN_STREAM_PTR stream);
};

#define ln_variant_init(v)                (v)->vt = LN_VT_NONE;
#define ln_variant_clear(thrd,v)          (ln_types[(v)->vt]->clear)(thrd, v)
#define ln_variant_hash(v)                (ln_types[(v)->vt]->hash) (v)
#define ln_variant_chg(thrd,v,ty)         ( ((v)->vt == ty) ? 0 : (ln_types[ty]->chg)(thrd, v, ty) )

#define ln_variant_vtos(thrd,v,s,size)    (ln_types[(v)->vt]->vtos) (thrd, v, s, size)
#define ln_variant_stov(thrd,v,ty,s,size) (ln_types[ty     ]->stov) (thrd, v, s, size)
#define ln_variant_save(thrd,v,stream)    (ln_types[(v)->vt]->save) (thrd, v, stream)
#define ln_variant_load(thrd,v,ty,stream) (ln_types[ty     ]->load) (thrd, v, stream)

#define ln_variant_set_as_int32(thrd,v,n)
#define ln_variant_set_as_string(thrd,v,s)

/*
 *  Time String Format
 *  12
 *  12 [PM | AM]
 *  [PM | AM] 12
 *  12:00
 *  12:00 [PM | AM]
 *  [PM | AM] 12:00
 *  
 *  DATE String Format
 *  
 *  July 1 2010
 *  2010 July 1
 *  2010 / 3 / 1
 *  3-1 2010
 */
enum
{
  LN_DATE_YY_MM_DD = 1,
  LN_DATE_MM_DD_YY,
  LN_DATE_DD_MM_YY,
};


#endif//end of __COMMON_TYPE_H__
